#include "stdafx.h"
#include "XGifImpl.h"

#include "Util.h"
#include "TimerUtil.h"

//////////////////////////////////////////////////////////////////////////
template <class I>
CXGifImpl<I>::CXGifImpl()
{
    m_pGifDraw = NULL;

    m_uTimerId = g_nInvalidTimerId;

    m_ePlayMode = GPM_Default;
    m_nFrameDelayValue = 200;
}

template <class I>
CXGifImpl<I>::~CXGifImpl()
{
}

//////////////////////////////////////////////////////////////////////////
// IXGif
template <class I>
HRESULT CXGifImpl<I>::put_Gif(IN LPCTSTR szXNC)
{
    ReleaseData();

    m_strGifXNC = szXNC;

    HRESULT hResult = S_OK;
    if(m_pGifDraw == NULL)
    {
        hResult = Util::CreateObject(&m_pGifDraw);
        CHECK_HRESULT(hResult);
    }

    hResult = m_pGifDraw->put_GifPath(szXNC);
    AutoSizeImpl(FALSE);

    if(SUCCEEDED(hResult))
        Start();

    return hResult;
}

template <class I>
HRESULT CXGifImpl<I>::get_ImagePath(OUT BSTR* pbstrXNC)
{
    if(m_pGifDraw == NULL)
        return E_FAIL;

    return m_pGifDraw->get_ImagePath(pbstrXNC);
}

template <class I>
HRESULT CXGifImpl<I>::Start()
{
    if(m_uTimerId != g_nInvalidTimerId || GetFrameCount() <= 1)
        return S_OK;

    if(m_pGifDraw == NULL || !m_pGifDraw->IsDrawValid())
        return E_FAIL;

    m_uTimerId = TimerUtil::SetTimer(this, GetNextElapse(), 0);

    return S_OK;
}

template <class I>
HRESULT CXGifImpl<I>::Stop()
{
    if(m_uTimerId != g_nInvalidTimerId)
    {
        TimerUtil::KillTimer(m_uTimerId);
        m_uTimerId = g_nInvalidTimerId;
    }
    return S_OK;
}

template <class I>
void CXGifImpl<I>::SetPlayMode(GifPlayMode eMode)
{
    if(m_ePlayMode != eMode)
    {
        m_ePlayMode = eMode;
        Stop();
        Start();
    }
}

template <class I>
GifPlayMode CXGifImpl<I>::GetPlayMode()
{
    return m_ePlayMode;
}

template <class I>
void CXGifImpl<I>::SetFixedInterval(int nFrameDelayValue)
{
    if(m_nFrameDelayValue != nFrameDelayValue)
    {
        m_nFrameDelayValue = nFrameDelayValue;
        Stop();
        Start();
    }
}

template <class I>
int CXGifImpl<I>::GetFixedInterval()
{
    return m_nFrameDelayValue;
}

template <class I>
DWORD CXGifImpl<I>::GetFrameCount()
{
    if(m_pGifDraw == NULL)
        return 0;
    else
        return m_pGifDraw->GetFrameCount();
}

//////////////////////////////////////////////////////////////////////////
// IXFrame
template <class I>
void CXGifImpl<I>::GetAutoSize(OUT LPSIZE pAutoSize)
{
    if(m_pGifDraw == NULL)
        CXFrameImpl<I>::GetAutoSize(pAutoSize);
    else
        m_pGifDraw->get_GifSize(pAutoSize);
}

template <class I>
void CXGifImpl<I>::Draw(XCANVAS xCanvas, const RECT& rcDraw)
{
    superclass::Draw(xCanvas, rcDraw);

    if(m_pGifDraw != NULL)
    {
        RECT rcClient = {0};
        get_WindowRect(&rcClient);

        m_pGifDraw->Draw(xCanvas, &rcClient);
    }
}

//////////////////////////////////////////////////////////////////////////
// IXBaseObj

template <class I>
void CXGifImpl<I>::OnFinalRelease()
{
    superclass::OnFinalRelease();
    ReleaseData();
}

//////////////////////////////////////////////////////////////////////////
// CXGifImpl

template <class I>
void CXGifImpl<I>::ReleaseData()
{
    if(m_uTimerId != g_nInvalidTimerId)
    {
        TimerUtil::KillTimer(m_uTimerId);
        m_uTimerId = g_nInvalidTimerId;
    }
    if(m_pGifDraw != NULL)
    {
        m_pGifDraw->Release();
        m_pGifDraw = NULL;
    }
}

//////////////////////////////////////////////////////////////////////////
// IXTimer
template <class I>
void CXGifImpl<I>::OnTimer(UINT_PTR uTimerId, void* pData)
{
    if(m_pGifDraw == NULL)
    {
        TimerUtil::KillTimer(uTimerId);
        m_uTimerId = g_nInvalidTimerId;
    }
    else
    {
        m_pGifDraw->NextFrame();
        m_uTimerId = TimerUtil::ResetTimer(m_uTimerId, GetNextElapse());
        if(IsVisible())
            Invalidate();
    }
}

//////////////////////////////////////////////////////////////////////////
// CXControlImpl
template <class I>
void CXGifImpl<I>::OnCreate()
{
    superclass::OnCreate();

    if(m_pGifDraw != NULL && m_pGifDraw->IsDrawValid())
        Start();
}